package interview.problem1;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class TrainMap extends Graph {
	public TrainMap(String filename) {
		super();
		createMap(filename);
	}

	private String readGraphData(String filename) throws IOException,
			FileNotFoundException {
		BufferedReader dataFile = new BufferedReader(new FileReader(filename));
		String line, data;
		data = "";
		while ((line = dataFile.readLine()) != null) {
			data += line;
		}
		return data;
	}

	/**  
	* @Title: tr  
	* @Description: 返回指定的Unicode字符表示的int值  
	* @param @param v
	* @param @return    设定文件  
	* @return int    对于有向图的索引号
	* @throws  
	*/
	private int tr(char v) {
		return Character.getNumericValue(v) - 10;
	}

	/**  
	* @Title: createMap  
	* @Description: 通过文件创建有向图  
	* @param @param filename    文件全路径
	* @return void    返回类型  
	* @throws  
	*/
	public void createMap(String filename) {
		String data;
		try {
			data = readGraphData(filename);
		} catch (Exception e) {
			System.out.println("Could not read graph data");
			System.out.println(e.toString());
			return;
		}

		String[] edges = data.split("[\\s]*,[\\s]*");
		int i;
		for (i = 0; i < edges.length; i++) {
			//获取有向图边权重
			int weight = Integer.parseInt(edges[i].substring(2));
			try {
				//在有向图中增加一个两点之间的关系
				addEdge(tr(edges[i].charAt(0)), tr(edges[i].charAt(1)), weight);
			} catch (GraphException e) {
				System.out.println(e.errorMsg());
			}
		}
	}

	// answers questions 1-5
	/**  
	* @Title: routeDistance  
	* @Description: 计算路径距离,1-5题入口
	* @param @param route 路径
	* @param @return    设定文件  
	* @return Object    返回类型  
	* @throws  
	*/
	public Object routeDistance(String route) {
		int i, rd = 0;
		try {
			for (i = 0; i < (route.length() - 1);) {
				rd += distance(tr(route.charAt(i)), tr(route.charAt(++i)));
			}
		} catch (GraphException e) {
			return "No such route";
		}

		return new Integer(rd);
	}

	/**  
	* @Title: shortestPathDist  
	* @Description: 查询两点间的最短路径 8，9题入口
	* @param @param start
	* @param @param end
	* @param @return    设定文件  
	* @return Object    返回类型  
	* @throws  
	*/
	public Object shortestPathDist(char start, char end) {
		try {
			return new Integer(shortestPath(tr(start), tr(end)));
		} catch (GraphException e) {
			return e.errorMsg();
		}
	}

	// answers question 10
	public Object numberOfPaths_Distance(char start, char end, int maxDist) {
		try {
			return new Integer(
					allPathsDistance(tr(start), tr(end), maxDist).length);
		} catch (GraphException e) {
			return e.errorMsg();
		}
	}

	// answers question 6
	/**  
	* @Title: 计算停靠点小于某一个值的所有路径数,6题入口
	* @Description:  
	* @param @param start
	* @param @param end
	* @param @param maxHops
	* @param @return    设定文件  
	* @return Object    返回类型  
	* @throws  
	*/
	public Object numberOfPaths_MaxHops(char start, char end, int maxHops) {
		try {
			return new Integer(allPathsHops(tr(start), tr(end), maxHops).length);
		} catch (GraphException e) {
			return e.errorMsg();
		}
	}

	// answers question 7
	public Object numberOfPaths_ExactHops(char start, char end, int hops) {
		int[] pathLengths;
		try {
			pathLengths = allPathsHops(tr(start), tr(end), hops);
		} catch (GraphException e) {
			return e.errorMsg();
		}

		int i, paths = 0; // count paths that are exactly hops long
		for (i = 0; i < pathLengths.length; i++)
			if (pathLengths[i] == hops)
				paths += 1;

		return new Integer(paths);
	}
}
